import React, { useMemo, useState, useEffect } from 'react';
import { observer } from 'mobx-react-lite';
import {
  Form, TextField, Button, Table, DataSet, SelectBox, Icon, message, Password, Tooltip,
} from 'choerodon-ui/pro';
import { CopyToClipboard } from 'react-copy-to-clipboard';
import { NewTips } from '@choerodon/components';
import {
  Action, CONSTANTS, axios,
} from '@choerodon/master';
import Record from 'choerodon-ui/pro/lib/data-set/Record';
import { Alert } from 'choerodon-ui';
import { Modal } from '@choerodon/master/lib/components/modal';
import { omit, remove } from 'lodash';
import moment from 'moment';
import uuidV1 from 'uuid';
import FormDs from './formDataSet';
import TableDs from './tableDataSet';
import TriggerPlanForm, { triggerModeData } from '../trigger-plan-form';
import CurlContent from '../curl';
import { dateData } from '../trigger-plan-form/formDataSet';
import { handleCopyOk } from '@/routes/continuous-deployment/utils';

import './index.less';
import { TAction } from '../../Content';

const modalkey1 = Modal.key();
const modalkey2 = Modal.key();
const modalkey3 = Modal.key();
const modalkey4 = Modal.key();
const {
  MODAL_WIDTH: {
    MIN,
  },
} = CONSTANTS;
const { Column } = Table;

interface IProps {
  formData: any
  pipelineId: string | undefined
  projectId: string
  curlText: string
  triggerAddress: string
  personalToken: string
  type: TAction
  onModalOk: (data: any) => void
}

const Index: React.FC<IProps> = (props) => {
  const {
    // @ts-ignore
    modal, formData, pipelineId, projectId, curlText, personalToken, triggerAddress,
    onModalOk, type,
  } = props;
  const prefixCls = 'c7ncd-continuousDeployment-operation-basic-configuration-form';

  const [tokenVisible, setTokenVisible] = useState(false);
  const [isProjectOwner, setIsProjectOwner] = useState(false);

  useEffect(() => {
    async function asyncFuc() {
      const res = await axios.get(`/iam/choerodon/v1/projects/${projectId}/check_admin_permission`);
      setIsProjectOwner(res);
    }
    asyncFuc();
  }, []);

  const formDs = useMemo(() => {
    const ds = new DataSet(FormDs({ pipelineId }));
    ds.loadData([omit(formData, 'pipelineScheduleList')]);
    return ds;
  }, []);

  const tableDs = useMemo(() => {
    const ds = new DataSet(TableDs({}));
    ds.loadData(formData.pipelineScheduleList);
    return ds;
  }, []);

  const handleTimingTriggerModalOk = (timingTriggerData: any, index: number) => {
    if (index === -1) { // 创建
      tableDs.create(timingTriggerData);
    } else {
      const data = tableDs.toData();
      data[index] = timingTriggerData;
      tableDs.loadData(data);
    }
  };

  const handleTimingTriggerOperation = (tableRecord?: Record) => {
    let data;
    const dataRecordIndex = tableRecord ? tableRecord.index : -1;
    const existNameArr:string[] = [];
    tableDs.forEach((item:Record) => {
      if (item !== tableRecord) {
        existNameArr.push(item?.get('name'));
      }
    });

    if (tableRecord) {
      data = omit(tableRecord?.toData(), '__dirty');
    }

    Modal.open({
      title: `${tableRecord ? '修改' : '添加'}定时触发计划`,
      key: modalkey1,
      drawer: true,
      style: {
        width: MIN,
      },
      children: (
        <TriggerPlanForm
          data={data}
          dataRecordIndex={dataRecordIndex}
          existNameArr={existNameArr}
          onModalOk={handleTimingTriggerModalOk}
        />
      ),
      okText: `${tableRecord ? '修改' : '添加'}`,
    });
  };

  const handleViewCurl = () => {
    const token = formDs?.current?.get('token');
    Modal.open({
      title: '生成curl命令',
      key: modalkey2,
      style: {
        width: 600,
      },
      children: (<CurlContent
        text={curlText}
        triggerAddress={triggerAddress}
        token={token}
        personalToken={personalToken}
      />
      ),
      okText: '复制',
      footer: (okBtn: any, cancelBtn: any) => (
        <div>
          {cancelBtn}
          <CopyToClipboard
            text={curlText}
          >
            {okBtn}
          </CopyToClipboard>
        </div>
      ),
    });
  };

  const handleDelete = (record: Record) => {
    Modal.open({
      title: '删除定时计划',
      key: modalkey3,
      style: {
        width: 600,
      },
      children: `确定删除定时计划${record?.get('name')}？`,
      okText: '删除',
      onOk: () => {
        const data = tableDs.toData();
        remove(data, (item:any) => item.id === record?.get('id'));
        tableDs.loadData(data);
      },
    });
  };

  const renderAction = ({ record }: { record: Record }) => {
    if (!isProjectOwner) {
      return '';
    }
    const actionDatas = [
      {
        service: [],
        text: '修改',
        action: () => { handleTimingTriggerOperation(record); },
      },
      {
        service: [],
        text: '删除',
        action: () => { handleDelete(record); },
      },
    ];
    return <Action data={actionDatas} style={{ position: 'relative', top: 2 }} />;
  };

  const renderTime = ({ record }: { record: Record }) => {
    let weekText = '';
    const weeksArr = record?.get('weekNumber').split(',');
    weeksArr.forEach((i: string) => {
      weekText += `${dateData.find((k) => k.value === i)?.text}，`;
    });
    weekText = weekText.substring(0, weekText.length - 1);
    const itemTriggerType = record?.get('triggerType');
    const itemTimeRange = record?.get('timeRange');
    const itemtriggerTypeText = triggerModeData
      .find((i: { value: any; }) => i.value === itemTriggerType)?.text;
    if (itemTriggerType === 'single') {
      return (
        <span>
          {`${weekText} / ${moment(record?.get('executeTime')).format('HH:mm')} 
            ${itemtriggerTypeText}`}
        </span>
      );
    } if (itemTriggerType === 'period') {
      return (
        <span>
          {`${weekText} / ${moment(itemTimeRange.start).format('h')}:00 ~ ${moment(itemTimeRange.end).format('h')}:00 间隔${record?.get('period')}分钟 ${itemtriggerTypeText}`}
        </span>
      );
    }
    return '';
  };

  const handleResetToken = () => {
    Modal.open({
      title: '重置个人令牌',
      key: modalkey4,
      style: {
        width: 600,
      },
      children: (
        <div className="reset-token-modal-content">
          <p>是否确认重置个人令牌？</p>
          <Alert
            showIcon
            type="warning"
            message="重置后之前的令牌指令将失效。"
          />
        </div>
      ),
      okText: '重置',
      onOk: () => {
        formDs?.current?.set('token', uuidV1());
        message.success('重置令牌成功');
      },
    });
  };

  const handleChangeTokenVisible = (v: boolean) => {
    setTokenVisible(!v);
  };

  const handleOk = async () => {
    const formValidateRes = await formDs?.current?.validate(true);
    if (!formValidateRes) {
      return false;
    }
    const currentFormData = formDs.toData()[0];
    const tableData = tableDs.toData();
    onModalOk({
      ...currentFormData,
      pipelineScheduleList: tableData,
    });
    return true;
  };
  modal.handleOk(handleOk);

  return (
    <div className={prefixCls}>
      <div className={`${prefixCls}-top`}>
        <Form dataSet={formDs}>
          <TextField name="name" />
        </Form>
        <div className="line" />
      </div>
      <div className={`${prefixCls}-bottom`}>
        <h3>触发规则</h3>
        <h4>
          <span>
            定时触发
            <NewTips helpText={(
              <>
                <p>周期触发: 需要选择日期，确定一个时间段，并给出触发的时间间隔；之后每周的这个时间段就会按照时间间隔执行定时计划。</p>
                <p>单次触发: 需要选择日期，同时需要指定一个特定的时间，之后每周的这个时间都会定时执行此计划。</p>
                <p>
                  项目所有者支持添加、编辑、删除定时任务，作为项目成员只能新增不可编辑、删除定时任务。
                </p>
              </>
            )}
            />
          </span>
          <Button icon="add" onClick={() => { handleTimingTriggerOperation(); }}>添加</Button>
        </h4>
        <Table dataSet={tableDs} queryBar={'none' as any}>
          <Column name="name" tooltip={'overflow' as any} width={150} />
          <Column renderer={renderAction} width={60} />
          <Column name="time" renderer={renderTime} tooltip={'overflow' as any} />
        </Table>
        <h4 className="h4-2">
          API 触发
        </h4>
        <div className="row-trigger-address">
          <CopyToClipboard
            text={triggerAddress}
            onCopy={handleCopyOk}
          >
            <Icon type="content_copy" />
          </CopyToClipboard>

          <Form dataSet={formDs}>
            <TextField
              disabled
              label="触发地址"
              value={`${triggerAddress.substring(0, 80)}...`}
            />
          </Form>
        </div>
        <Alert
          showIcon
          type="info"
          message={(
            <div className="content">
              <div className="left">需使用具有API 触发权限的令牌触发</div>
              <div className="right" role="none" onClick={() => { handleViewCurl(); }}>生成curl命令触发示例</div>
            </div>
          )}
        />
        <Form dataSet={formDs} className="row-token">
          {/* @ts-ignore */}
          <div className="row-token-content">
            {
              !tokenVisible && <Password name="token" disabled />
            }
            {
              tokenVisible && <TextField name="token" disabled />
            }
            <Tooltip title="项目令牌更新后之前令牌指令将失效。" placement="bottom">
              <Button onClick={handleResetToken}>重置</Button>
            </Tooltip>
            {
             !tokenVisible && <Icon type="visibility-o" onClick={() => { handleChangeTokenVisible(false); }} />
            }
            {
              tokenVisible && <Icon type="visibility_off-o" onClick={() => { handleChangeTokenVisible(true); }} />
            }
            <CopyToClipboard
              text={formDs?.current?.get('token')}
              onCopy={handleCopyOk}
            >
              <Icon type="content_copy" />
            </CopyToClipboard>
          </div>
        </Form>
        <h4>
          应用服务版本生成触发
        </h4>
        <Form dataSet={formDs}>
          <SelectBox
            name="appVersionTriggerEnable"
          >
            <SelectBox.Option value>是</SelectBox.Option>
            <SelectBox.Option value={false}>否</SelectBox.Option>
          </SelectBox>
        </Form>
      </div>
    </div>
  );
};

export default observer(Index);
